#include <iostream>
using std::cout;
using std::endl;

class Base {
public:
    Base(long base)
    : _base(base)
    { cout << "Base()" << endl; }

    virtual void display(){
        cout << "Base::display()" << endl;
    }

    ~Base()
    { 
        cout << "~Base()" << endl; 
    }

    long _base = 10;
};

class Derived
: public Base 
{
public:
    Derived(long base,long derived)
    : Base(base)
    , _derived(derived)
    { 
        cout << "Derived(long)" << endl; 
    }

    void print() const{
        cout << "Derived::print " << _derived << endl;
    }

    ~Derived(){ 
        cout << "~Derived()" << endl; 
    }

    long _derived;
};

void test0(){
    Base base(1);
    Derived d1(2,3);

    //会调用Base类的赋值运算符函数
    //Base & operator=(const Base & rhs);
    //base.operator=(d1);
    //形参初始化的过程const Base & rhs = d1;
    base = d1;//ok
    /* d1 = base;//error */

    //Derived*转换成Base*
    //引用的绑定和对象的复制类似
    //都是由派生类向基类进行转换（向上转换）
    //直接进行向上转换都是可行的
    //
    //pbase实际上指向Derived对象中的Base类基类子对象
    Base * pbase = &d1;//ok
    pbase->display();
    /* pbase->print(); */

    //由基类向派生类进行转换（向下转换）
    //直接进行向下转换都是不行的
    //pderived需要控制一片非法空间，不能成功
    /* Derived * pderived = &base;//error */

    Base & bref = d1;//ok
    /* Derived & dref = base;//error */
}

void test1(){
    Base base(1);
    Derived d1(2,3);

    //用C的方式进行强制转换 —— 向下转换
    //无论合理与否都会得到一个派生类指针
    Base * pbase = &d1;
    Derived * pd = (Derived*)pbase;//合理
    pd->print();

    Base * pbase2 = &base;
    Derived * pd2 = (Derived*)pbase2;//不合理
    pd2->print();

    //直接向下转换会无法通过
    /* Derived * pd3 = pbase; */
}

void test2(){
    Base base(1);
    Derived d1(2,3);

    Base * pbase = &d1;
    /* Base * pbase = &base; */
    //针对不合理的向下转换
    //得到的是一个Derived*类型的空指针
    Derived * pd = dynamic_cast<Derived*>(pbase);

    if(pd){
        cout << "转换成功" << endl;
        pd->print();
    }else{
        cout << "转换失败" << endl;
    }


}

int main(void){
    test2();
    return 0;
}
